<?php

declare(strict_types=1);

namespace App\Service;

use App\Model\AftersaleProduct;
use App\Model\FlyOrder;
use App\Model\FlyOrderCommission;
use App\Model\FlyOrderProduct;
use App\Model\Industry;
use App\Model\Moment;
use Hyperf\DbConnection\Db;

/**
 * 用户订单支付服务
 * Class FlyPayOrderService
 * @package App\Service
 */
class FlyPayOrderService extends BaseService
{

    /**
     * 查询用户订单(未支付)
     * @param string $order_sn
     * @return array
     */
    public function getPayOrderBySn(string $order_sn): array
    {
        $pay_order = $this->getModelInstance()
            ->with(['with_shop_order', 'with_products'])
            ->where(['pay_order_sn' => $order_sn, 'paid_price' => 0])
            ->first();
        if (empty($pay_order)) {
            return [];
        }
        return $pay_order->toArray();
    }

    /**
     * 商城支付单回调状态修改
     * @param string $order_sn
     * @param string $pay_type
     * @param string $pay_method
     * @param string $outer_sn 外部支付单号
     * @return bool
     */
    public function payOrderNotifyPay(string $order_sn, string $pay_type, string $pay_method, string $outer_sn)
    {
        $order = $this->getPayOrderBySn($order_sn);
        if (empty($order)) {
            return false;
        }
        // 更新支付单
        $re = $this->getModelInstance()
            ->where(['pay_order_sn' => $order_sn])
            ->update([
                'is_pay' => 1,
                'paid_price' => Db::raw('pay_price'),
                'pay_time' => time(),
                'pay_type' => $pay_type,
                'pay_method' => $pay_method,
                'pay_outer_sn' => $outer_sn
            ]);
        if (!$re) {
            echo "订单支付单状态修改失败";
            return false;
        }
        // 更新支付关联订单支付状态 todo 依赖注入冲突
        $re = make(FlyOrderService::class)->orderNotifyPay($order['pay_order_id'], $pay_type, $pay_method, $outer_sn);
        if (!$re || $re != count($order['with_shop_order'])) {
            echo "商城订单状态同步失败";
            return false;
        }
        try {
            // 分销用户提成
            foreach ($order['with_shop_order'] as $shop_order) {
                foreach ($shop_order['with_products'] as $with_product) {
                    if ($with_product['moments_id'] > 0) {
                        // 为分销下单-为分销成功用户提成
                        $moment_info = make(Moment::class)
                            ->where(['id' => $with_product['moments_id']])
                            ->whereHas('with_valid_dr', function ($where) use ($with_product) {
                                $where->where('product_id', $with_product['product_id']);
                            })->first();
                        if (!empty($moment_info) && !empty($moment_info->with_valid_dr) && !empty($moment_info->with_valid_dr->with_shop_ad)) {
                            $commission = $moment_info->with_valid_dr->with_shop_ad;
                            FlyOrderCommission::query()
                                ->insert([
                                    'order_id' => $shop_order['order_id'],
                                    'order_sku_id' => $with_product['sku_id'],
                                    'op_id' => $with_product['id'],
                                    'moments_id' => $moment_info->id,
                                    'moments_product_id' => $with_product['product_id'],
                                    'single_price' => $with_product['single_price'],
                                    'quantity' => $with_product['quantity'],
                                    'commission_rate' => $commission->rate,
                                    'subtotal' => ($commission->rate / 100) * $with_product['subtotal']
                                ]);
                        }
                    }
                }
            }
        } catch (\Throwable $exception) {
            echo $exception->getMessage();
            return false;
        }
        if ($order['order_style'] == 1) {
            // 更新订单商品售后参数
            $af_set = make(FlyOrderProduct::class)
                ->leftJoin('fly_link_industry', 'fly_order_product.industry_id', '=', 'fly_link_industry.industry_id')
                ->leftJoin('fly_after_sell_set', 'fly_link_industry.link_id', '=', 'fly_after_sell_set.id')
                ->where(['pay_order_id' => $order['pay_order_id']])
                ->whereIn('fly_link_industry.type', [5, 6])
                ->select([
                    Db::raw('ANY_VALUE(wf_fly_order_product.id) as p_id'),
                    Db::raw('ANY_VALUE(wf_fly_order_product.is_virtual) as is_virtual'),
                    Db::raw('ANY_VALUE(wf_fly_link_industry.industry_id) as industry_id'),// 行业
                    Db::raw("ANY_VALUE(wf_fly_after_sell_set.type) as af_type"),//设置类型
                    Db::raw("ANY_VALUE(wf_fly_after_sell_set.after_sell_type) as type"), // 行业支持的售后类型
                    Db::raw("ANY_VALUE(wf_fly_after_sell_set.days) as days") // 行业支持的售后天数
                ])->get();
            $sets = empty($af_set) ? [] : $af_set->toArray();

            $products = [];
            // 订单商品对应的售后服务期限
            foreach ($sets as $set) {
                if ($set['af_type'] == 2) {
                    // 无理由期限设置
                    $products[$set['p_id']]['support_no_reason'] = 1;// 支持无理由
                    $products[$set['p_id']]['no_reason_days'] = $set['days'];// 无理由期限
                } else {
                    // 商品支持的售后类型和可申请售后天数
                    if (isset($products[$set['p_id']]['days'])) {
                        if (isset($products[$set['p_id']]['days']) && $products[$set['p_id']]['days'] < $set['days']) {
                            $products[$set['p_id']]['days'] = $set['days'];
                        }
                    } else {
                        $products[$set['p_id']]['days'] = $set['days'];
                    }
                    if (isset($products[$set['p_id']]['type'])) {
                        $products[$set['p_id']]['type'][] = $set['type'];
                    } else {
                        $products[$set['p_id']]['type'] = [];
                        $products[$set['p_id']]['type'][] = $set['type'];
                    }
                }
                $products[$set['p_id']]['is_virtual'] = $set['is_virtual'];
            }
            // 支付成功更新售后期限
            foreach ($products as $p_id => $p_set) {
                $af_sets = [
                    'free_num' => (!empty($p_set['days']) || !empty($p_set['no_reason_days'])) ? (Db::raw("quantity")) : 0,
                    'support_af_types' => !isset($p_set['type']) ? "" : implode(',', array_unique($p_set['type'])), // 支持的售后类型
                    'can_af_apply_duration' => $p_set['days'] ?? 0, // 售后期限
                    'af_no_reason_duration' => $p_set['no_reason_days'] ?? 0,// 无理由期限
                    'support_no_reason' => $p_set['support_no_reason'] ?? 0// 支持无理由
                ];
                // 虚拟产品只支持仅退款
                if ($p_set['is_virtual'] == 1) {
                    if (in_array(1, array_unique($p_set['type']))) {
                        $af_sets['support_af_types'] = 1;
                    } else {
                        $af_sets['support_af_types'] = 0;
                    }
                }

                // 无理由售后在支持退货退款或支持换货的基础上
                if (isset($p_set['type'])) {
                    if (!in_array(2, $p_set['type']) && !in_array(3, $p_set['type'])) {
                        $af_sets['af_no_reason_duration'] = 0;
                        $af_sets['support_no_reason'] = 0;
                    }
                } else {
                    // 不支持售后
                    $af_sets['af_no_reason_duration'] = 0;
                    $af_sets['support_no_reason'] = 0;
                }
                make(FlyOrderProduct::class)->where(['id' => $p_id])->update($af_sets);
            }
        } else {
            // 可申请售后数量
            make(FlyOrderProduct::class)
                ->where('pay_order_id', '=', $order['pay_order_id'])
                ->update(['free_num' => Db::raw('quantity')]);
        }
        return true;

    }

    /**
     * 生成支付单并返回支付单ID
     * @param array $orderData
     * @param int $style_type
     * @return int
     */
    public function createOrder(array $orderData, $style_type = FlyOrderService::STYLE_SHOP): int
    {
        if (empty($orderData) || (empty($orderData['pay_price']) && $style_type != FlyOrderService::STYLE_SEAT) || empty($orderData['pay_order_sn'])) {
            return 0;
        }
        $instance = $this->getModelInstance();
        $instance->create_time = time();
        $instance->pay_order_sn = $orderData['pay_order_sn'];
        $instance->user_id = $orderData['user_id'];
        $instance->pay_price = $orderData['pay_price'];
        $instance->product_price = $orderData['product_price'];
        $instance->delivery_type = $orderData['delivery_type'] ?? 0;
        $instance->delivery_price = $orderData['delivery_price'] ?? 0;
        $instance->is_virtual = $orderData['is_virtual'] ?? 0;
        $instance->coupon_price = $orderData['coupon_price'] ?? 0;
        if (!empty($orderData['order_style'])) {
            $instance->order_style = $orderData['order_style'];
        }
        // 美食模块订座可能不需要押金
        if ($style_type == FlyOrderService::STYLE_SEAT) {
            $instance->pay_time = $orderData['pay_time'] ?? 0;
            $instance->is_pay = $orderData['is_pay'] ?? 0;
        }
        if (!$instance->save()) {
            return 0;
        }
        return $instance->pay_order_id;
    }

    /**
     * 关闭支付单
     * @param string $pay_order_sn
     * @param int $user_id
     * @param int $reason_id
     * @param string $reason
     * @return bool
     */
    public function closePayOrder(string $pay_order_sn, int $user_id, int $reason_id, string $reason): bool
    {
        return (bool)$this->getModelInstance()
            ->where(['pay_order_sn' => $pay_order_sn, 'is_close' => 0, 'is_pay' => 0, 'user_id' => $user_id])
            ->update(['is_close' => 1, 'close_time' => time(), 'close_reason_id' => $reason_id, 'close_reason' => $reason]);
    }

    /**
     * 获取支付单模型
     * @return mixed
     */
    public function getPayOrderInstance()
    {
        return $this->getModelInstance();
    }
}